-- 补全
return {
  {
    "hrsh7th/nvim-cmp",
    dependencies = {
      "hrsh7th/cmp-emoji",
      "hrsh7th/cmp-cmdline",
      "hrsh7th/cmp-path",
      -- {
      --   "Exafunction/codeium.nvim",
      --   -- enabled = false,
      --   cmd = "Codeium",
      --   build = ":Codeium Auth",
      --   opts = {},
      -- },
      -- {
      --   "tzachar/cmp-tabnine",
      --   build = {
      --     "./install.sh",
      --     ":CmpTabnineHub",
      --   },
      --   dependencies = "hrsh7th/nvim-cmp",
      --   opts = {
      --     max_lines = 1000,
      --     max_num_results = 3,
      --     sort = true,
      --   },
      --   config = function(_, opts)
      --     require("cmp_tabnine.config"):setup(opts)
      --   end,
      -- },
    },

    -- @param opts cmp.ConfigSchema
    opts = function(_, opts)
      local cmp = require("cmp")

      opts.snippet = {
        -- REQUIRED - you must specify a snippet engine
        expand = function(args)
          -- vim.fn["vsnip#anonymous"](args.body) -- For `vsnip` users.
          require("luasnip").lsp_expand(args.body) -- For `luasnip` users.
          -- require('snippy').expand_snippet(args.body) -- For `snippy` users.
          -- vim.fn["UltiSnips#Anon"](args.body) -- For `ultisnips` users.
          -- vim.snippet.expand(args.body) -- For native neovim snippets (Neovim v0.10+)
        end,
      }
      opts.window = {
        completion = cmp.config.window.bordered(),
        documentation = cmp.config.window.bordered(),
      }
      local has_words_before = function()
        unpack = unpack or table.unpack
        local line, col = unpack(vim.api.nvim_win_get_cursor(0))
        return col ~= 0 and vim.api.nvim_buf_get_lines(0, line - 1, line, true)[1]:sub(col, col):match("%s") == nil
      end

      -- opts.sources = cmp.config.sources(vim.list_extend(opts.sources, { { name = "cmdline" } }))
      opts.sources = cmp.config.sources({
        { name = "buffer", keyword_length = 2 },
        { name = "nvim_lsp", keyword_length = 1 },
        { name = "nvim_lua", keyword_length = 1 },
        { name = "vsnip", keyword_length = 1 },
        { name = "luasnip", keyword_length = 1 },
        { name = "path", keyword_length = 1 },
        -- { name = "codeium", keyword_length = 1 },
        -- { name = "cmp_tabnine", group_index = 1, priority = 100 },
        { name = "emoji", keyword_length = 1 },
      })

      -- `/` cmdline setup.
      cmp.setup.cmdline("/", {
        mapping = cmp.mapping.preset.cmdline(),
        sources = {
          { name = "buffer" },
        },
      })
      -- `:` cmdline setup.
      cmp.setup.cmdline(":", {
        mapping = cmp.mapping.preset.cmdline(),
        sources = cmp.config.sources({
          { name = "path" },
        }, {
          {
            name = "cmdline",
            option = {
              ignore_cmds = { "Man", "!" },
            },
          },
        }),
      })

      local cmp_select_opts = {
        behavior = cmp.SelectBehavior.Select,
      }

      local luasnip = require("luasnip")

      local select_next = cmp.mapping(function(fallback)
        if cmp.visible() then
          cmp.select_next_item()
        elseif luasnip.expand_or_jumpable() then
          luasnip.expand_or_jump()
        elseif has_words_before() then
          cmp.complete()
        else
          fallback()
        end
      end, { "i", "s" })
      local select_prev = cmp.mapping(function(fallback)
        if cmp.visible() then
          cmp.select_prev_item()
        elseif luasnip.jumpable(-1) then
          luasnip.jump(-1)
        else
          fallback()
        end
      end, { "i", "s" })

      -- 使用tab切换补全 tab时可能会乱跳转未解决
      -- opts.mapping = cmp.mapping.preset.insert({
      --   ["<C-Space>"] = cmp.mapping.complete(),
      --   ["<C-e>"] = cmp.mapping.abort(),
      --   ["<C-b>"] = cmp.mapping.scroll_docs(-4),
      --   ["<C-f>"] = cmp.mapping.scroll_docs(4),
      --
      --   ["<Up>"] = cmp.mapping.select_prev_item(cmp_select_opts),
      --   ["<Down>"] = cmp.mapping.select_next_item(cmp_select_opts),
      --
      --   ["<Tab>"] = select_next,
      --   ["<S-Tab>"] = select_prev,
      --   ["<CR>"] = cmp.mapping.confirm({ select = true }),
      -- })

      opts.formatting.format = LazyVim.inject.args(opts.formatting.format, function(entry, item)
        -- Hide percentage in the menu
        if entry.source.name == "cmp_tabnine" then
          item.menu = ""
        end
      end)
    end,
  },
}
